package com.yixin.hospital.controller;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yixin.hospital.common.ApiResult;
import com.yixin.hospital.common.Constant;
import com.yixin.hospital.entity.bo.PageInfo;
import com.yixin.hospital.entity.domain.*;
import com.yixin.hospital.entity.dto.req.patient.PatientAddReqDTO;
import com.yixin.hospital.entity.dto.req.patient.PatientEditReqDTO;
import com.yixin.hospital.entity.vo.PatientVo;
import com.yixin.hospital.service.*;
import com.yixin.hospital.utils.DateUtil;
import com.yixin.hospital.utils.JwtUtil;
import com.yixin.hospital.utils.RegExUtil;
import com.yixin.hospital.utils.SqeUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.BeanUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

import static com.yixin.hospital.enums.ResponseCodeEnum.PATIENT_INTRODUCER;
import static com.yixin.hospital.enums.ResponseCodeEnum.USER_EXIT;

@RestController
@RequestMapping("/patient")
@Api(value = "患者信息管理", tags = "患者信息商管理")
public class PatientController {

    @Resource
    PatientService patientService;
    @Resource
    PatientSourceService patientSourceService;
    @Resource
    PatientAddressService patientAddressService;
    @Resource
    UserService userService;
    @Resource
    JobDutyService jobDutyService;
    @Resource
    GuidanceService guidanceService;


    @GetMapping("/list")
    @ApiOperation(value = "患者列表")
    public ApiResult<?> list(@RequestParam int currentPage, @RequestParam int pageSize, String name, HttpServletRequest request) {
        Long userId = JwtUtil.getUserId(request.getHeader(Constant.AUTHORIZATION));
        // 查询用户职务
        User user = userService.getById(userId);
        boolean isDesensitization = true;
        List<JobDuty> JobDutyList = jobDutyService.list(new LambdaQueryWrapper<JobDuty>().in(JobDuty::getId, Arrays.asList(user.getJobDuty().split(","))));
        for (JobDuty jobDuty : JobDutyList) {
            // 不脱敏
            if (jobDuty.getIsDesensitization() == 0) {
                isDesensitization = false;
                break;
            }
        }

        LambdaQueryWrapper<Patient> patientQueryWrapper = new LambdaQueryWrapper<>();
        if (Strings.isNotBlank(name)) {
            patientQueryWrapper.like(Patient::getName, name).or().like(Patient::getCode, name).or().likeRight(Patient::getPhone, name).or().like(Patient::getIdCard, name);
        }
        patientQueryWrapper.orderByAsc(Patient::getName);
        Page<Patient> page = patientService.page(Page.of(currentPage, pageSize), patientQueryWrapper);
        PageInfo<PatientVo> pageInfo = new PageInfo<>();
        BeanUtil.copyProperties(page, pageInfo);
        pageInfo.setRecords(BeanUtil.copyToList(page.getRecords(), PatientVo.class));
        for (PatientVo record : pageInfo.getRecords()) {
            if (Objects.nonNull(record.getMasterDoctor())) {
                User masterDoctor = userService.getById(record.getMasterDoctor());
                record.setMasterDoctorName(masterDoctor.getName());
            }
            PatientSource source = patientSourceService.getById(record.getSource());
            record.setSourceName(source.getSource());
            LambdaQueryWrapper<PatientAddress> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(PatientAddress::getPatientId, record.getId());
            List<PatientAddress> list = patientAddressService.list(queryWrapper);
            record.setAddressList(list);
//            record.setPhone(isDesensitization ? RegExUtil.desensitizePhone(record.getPhone()) : record.getPhone());
            record.setPhone(record.getPhone().length() == 11 ? record.getPhone().substring(7): record.getPhone());
            record.setPhoneTwo(StringUtils.isNotBlank(record.getPhoneTwo()) && record.getPhoneTwo().length() == 11 ? record.getPhoneTwo().substring(7): record.getPhoneTwo());
            record.setPhoneThree(StringUtils.isNotBlank(record.getPhoneThree()) && record.getPhoneThree().length() == 11 ? record.getPhoneThree().substring(7): record.getPhoneThree());
            record.setPhoneFour(StringUtils.isNotBlank(record.getPhoneFour()) && record.getPhoneFour().length() == 11 ? record.getPhoneFour().substring(7): record.getPhoneFour());

            // 计算年龄
            record.setAge(DateUtil.getAge(record.getBirthday()));
            // 计算入籍时间
            record.setJoinDuration(DateUtil.diffTime(record.getCreatedTime()));
            // 获取就诊时间
//            Guidance guidance = guidanceService.getOne(new LambdaQueryWrapper<Guidance>().eq(Guidance::getPatientId, record.getId()).select(Guidance::getCreatedTime));
//            record.setVisitDate(guidance.getCreatedTime());
            // 计算就诊状态 todo
            record.setVisitStatus("");
        }
        return ApiResult.success(pageInfo);
    }

    @GetMapping("/allList")
    @ApiOperation(value = "患者下拉框")
    public ApiResult<?> allList() {
        LambdaQueryWrapper<Patient> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByAsc(Patient::getName);
        return ApiResult.success(patientService.list(queryWrapper));
    }

    @PostMapping("/add")
    @ApiOperation(value = "添加患者")
    public ApiResult<?> add(@Valid @RequestBody PatientAddReqDTO patientAddReqDTO, HttpServletRequest request) {
        if(!checkPatient(patientAddReqDTO.getSource(), patientAddReqDTO.getIntroducer())) return ApiResult.error(PATIENT_INTRODUCER);
        if(!checkExistPatient(patientAddReqDTO.getPhone(), patientAddReqDTO.getPhoneTwo(), patientAddReqDTO.getIdCard())) return ApiResult.error(USER_EXIT);
        String userName = JwtUtil.getName(request.getHeader(Constant.AUTHORIZATION));
        Patient patient = new Patient();
        BeanUtils.copyProperties(patientAddReqDTO, patient);
        patient.setCode("H" + (char)(int)SqeUtil.randomInt(65, 91) + (char)(int)SqeUtil.randomInt(65, 91) + SqeUtil.getRandomByLength(6));
        patient.setCreatedBy(userName);
        patient.setUpdatedBy(userName);
        patientService.save(patient);
        List<PatientAddress> addressList = patientAddReqDTO.getAddressList();
        if (!CollectionUtils.isEmpty(addressList)) {
            for (PatientAddress address : addressList) {
                PatientAddress patientAddress = new PatientAddress();
                patientAddress.setPatientId(patient.getId());
                patientAddress.setRetailStore(address.getRetailStore());
                patientAddress.setDistance(address.getDistance());
                patientAddress.setMultiAddressDes(address.getMultiAddressDes());
                patientAddress.setAddress(address.getAddress());
                patientAddress.setType(address.getType());
                patientAddress.setIsDefault(address.getIsDefault());
                patientAddress.setContactName(address.getContactName());
                patientAddress.setContactPhone(address.getContactPhone());
                patientAddress.setUpdatedBy(userName);
                patientAddress.setCreatedBy(userName);
                patientAddressService.save(patientAddress);
            }
        }
        return ApiResult.success();
    }

    private boolean checkExistPatient(String phone1, String phone2, String idCard) {
        LambdaQueryWrapper<Patient> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Patient::getPhone, phone1);
        queryWrapper.or().eq(Patient::getIdCard, idCard);
        if (Strings.isNotBlank(phone2)) {
            queryWrapper.or().eq(Patient::getPhoneTwo, phone2);
        }
        List<Patient> list = patientService.list(queryWrapper);
        if (CollectionUtils.isEmpty(list)) return true;
        return false;
    }

    private boolean checkPatient(Long source, Long introducer) {
        if (Objects.equals(source, 1L) && Objects.isNull(introducer)) return false;
        if (Objects.equals(source, 2L) && Objects.isNull(introducer)) return false;
        return true;
    }

    @PutMapping("/edit")
    @ApiOperation(value = "编辑患者")
    public ApiResult edit(@Valid @RequestBody PatientEditReqDTO patientEditReqDTO, HttpServletRequest request) {
        if(!checkPatient(patientEditReqDTO.getSource(), patientEditReqDTO.getIntroducer())) return ApiResult.error(PATIENT_INTRODUCER);
        String userName = JwtUtil.getName(request.getHeader(Constant.AUTHORIZATION));
        Patient patient = new Patient();
        BeanUtils.copyProperties(patientEditReqDTO, patient, "phone", "phoneTwo", "phoneThree");
//        if (!patientEditReqDTO.getPhone().contains("*")) patient.setPhone(patientEditReqDTO.getPhone());
        if (patientEditReqDTO.getPhone().length() == 11) patient.setPhone(patientEditReqDTO.getPhone());
        if (Objects.nonNull(patientEditReqDTO.getPhoneTwo()) && patientEditReqDTO.getPhoneTwo().length() == 11) patient.setPhoneTwo(patientEditReqDTO.getPhoneTwo());
        if (Objects.nonNull(patientEditReqDTO.getPhoneThree()) && patientEditReqDTO.getPhoneThree().length() == 11) patient.setPhoneThree(patientEditReqDTO.getPhoneThree());
        patient.setUpdatedBy(userName);
        patientService.updateById(patient);
        List<PatientAddress> addressList = patientEditReqDTO.getAddressList();
        if (!CollectionUtils.isEmpty(addressList)) {
            LambdaQueryWrapper<PatientAddress> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(PatientAddress::getPatientId, patientEditReqDTO.getId());
            patientAddressService.remove(queryWrapper);
            for (PatientAddress address : addressList) {
                PatientAddress patientAddress = new PatientAddress();
                patientAddress.setPatientId(patient.getId());
                patientAddress.setRetailStore(address.getRetailStore());
                patientAddress.setDistance(address.getDistance());
                patientAddress.setMultiAddressDes(address.getMultiAddressDes());
                patientAddress.setAddress(address.getAddress());
                patientAddress.setType(address.getType());
                patientAddress.setIsDefault(address.getIsDefault());
                patientAddress.setContactName(address.getContactName());
                patientAddress.setContactPhone(address.getContactPhone());
                patientAddress.setUpdatedBy(userName);
                patientAddress.setCreatedBy(userName);
                patientAddressService.save(patientAddress);
            }
        }
        return ApiResult.success();
    }

    @DeleteMapping("/remove/{id}")
    @ApiOperation(value = "删除患者")
    public ApiResult remove(@PathVariable int id) {
        patientService.removeById(id);
        return ApiResult.success();
    }

}
